import React, { createContext } from 'react'
import ReactDOM from 'react-dom/client';
import { AppLayout as DefaultLayout } from './layout';
import { ConstructorOf } from './declare';
import { SlotRegister, IslotRegister, IComponentSlot, ReducerRegister, IRegisterProps } from '.';
import { configureStore } from '@reduxjs/toolkit';
import 'antd/dist/reset.css'
import { Provider } from 'react-redux';
import { AppContext } from './appContext';


export interface IClientProps {
    root: HTMLElement;
    redux?: boolean;
    jwt?: boolean
    goLogin?: (args: Record<string, string>) => Promise<object>
    providers?: Array<{
        component: React.ComponentType<unknown>;
        props: Record<string, unknown>;
    }>,
    layout?: React.ComponentType<unknown>;
    modules: Array<ConstructorOf<unknown>>;
    
}


export class client {
    props: IClientProps;

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    modules: Array<any>;

    slotRegister: SlotRegister;
    reducerRegister: ReducerRegister;

    constructor(props: IClientProps) {
        this.props = props;
        this.slotRegister = new SlotRegister();
        this.reducerRegister = new ReducerRegister();
        this.modules = this.props.modules.map((module): InstanceType<typeof module> => new module());
        
        // this.register();
        
        this.registerComponent();

        this.registerReducer();

        this.render()
    }   

    // registerSlot = () => {
    //     this.modules.map((module) => {
    //         if (typeof module.register === 'function'){
    //             module.register(this.slotRegister)
    //         }
    //     })
    // }

    registerComponent = () => {
        this.modules.map(module => {
            if (typeof module.registerComponent === 'function'){
                module.registerComponent(this.slotRegister)
            }
        })
        console.log(this.slotRegister.slots);
    }

    registerReducer = () => {
        this.modules.map(module => {
            if (typeof module.registerReducer === 'function'){
                module.registerReducer(this.reducerRegister)
            }
        })
    }

    render() {
        const { root, redux, providers = [], jwt = false, goLogin } = this.props;
        const ctx = {
            slots: this.slotRegister.slots
        }

        const layoutSlot = this.slotRegister.slots["layout"]
        // const layoutDom = Layout ? <Layout/> : <DefaultLayout/>;

        const layoutDom = Array.isArray(layoutSlot) 
        ? layoutSlot.map((item: IRegisterProps, index) => {
            return <item.component key={index} {...item.props} jwt={jwt} goLogin={goLogin}/>
        })
        : null

        let providersDom = providers.reverse().reduce((pv, cv) => {
            return <cv.component {...cv.props}>{pv}</cv.component>
        }, layoutDom)

        if (redux) {
            const store = configureStore({
                reducer: this.reducerRegister.reducer,
            });
            providersDom = <Provider store={store}>{providersDom}</Provider>
        }

        ReactDOM.createRoot(root).render(
            // <React.StrictMode>
                <AppContext.Provider value={ctx}>
                    { providersDom }
                </AppContext.Provider>
            // </React.StrictMode>,
        )
    }
}